package com.ltmonitor.web.controller.video;

import com.ltmonitor.entity.TerminalCommand;
import com.ltmonitor.entity.VehicleData;
import com.ltmonitor.service.IOnlineVideoRequestService;
import com.ltmonitor.service.IVideoFileItemService;
import com.ltmonitor.service.IVideoMp4KeyFrameService;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.util.StringUtil;
import com.ltmonitor.util.VideoDataType;
import com.ltmonitor.video.entity.VideoFileItem;
import com.ltmonitor.video.entity.VideoMp4KeyFrame;
import com.ltmonitor.video.entity.VideoRequest;
import com.ltmonitor.video.entity.VideoServerConfig;
import com.ltmonitor.web.constants.FunctionConstant;
import com.ltmonitor.web.controller.command.TerminalCommandAction;
import com.ltmonitor.web.util.JsonMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 下发监听命令
 * 
 * @author DELL
 * 
 */
@Controller
@RequestMapping("/videoPlayBack")
public class VideoPlayBackAction extends TerminalCommandAction {

	@Autowired
	private IVideoFileItemService videoFileItemService;
	@Autowired
	private IOnlineVideoRequestService onlineVideoRequestService;

	@Autowired
	private IVideoMp4KeyFrameService videoMp4KeyFrameService;

	@RequestMapping("/view.action")
	public String view(Model m)
	{
		if(hasPlaybackVideoAuthority() == false)
			return "/video/noVideoPermission";
		VideoServerConfig vc = this.getVideoServerConfig();
		m.addAttribute("videoServerConfig", vc);
		//m.addAttribute("vehicleId", vehicleId);
		return "/video/videoPlayBack";
	}


    /**
     * 下发h音视频回放指令
	 * @return
     */
	@ResponseBody
	@RequestMapping("/sendRequest.action")
	public JsonMessage sendRequest(String plateNo, int channel, int streamType, int videoType, int storeType, int playbackType, int speed,
									 Date startDate, Date endDate) {

		if(hasPlaybackVideoAuthority() == false)
			return json(false, "对不起，你没有实时视频监控权限");
		try {
			StringBuilder sb = new StringBuilder();
			String videoServerIp = this.getVideoServerConfig().getVideoServerIp();
			int tcpPort = this.getVideoServerConfig().getVideoServerTcpPort();
			int udpPort = this.getVideoServerConfig().getVideoServerUdpPort();
			int videoDataType = VideoDataType.VIDEO_WITH_AUDIO;
			sb.append(videoServerIp).append(';').append(tcpPort).append(';')
					.append(udpPort).append(';').append(channel).append(';')
					.append(videoDataType).append(';').append(streamType).append(';')
					.append(storeType).append(';').append(playbackType).append(';')
					.append(speed).append(';').append(DateUtil.toStringByFormat(startDate,"yyyy-MM-dd HH:mm:ss")).append(';')
			        .append(DateUtil.toStringByFormat(endDate,"yyyy-MM-dd HH:mm:ss"));

			VehicleData vd = this.vehicleDataService.getVehicleByPlateNo(plateNo);
			String simNo = vd.getSimNo();
			List<VideoRequest> ls = onlineVideoRequestService.getOnlineVideoRequest(simNo, channel);
			if(ls.size() > 0) {
				onlineVideoRequestService.stopVideoRequest(this.getOnlineUser().getEntityId(),simNo, channel, this.getSession().getId(), streamType, videoDataType);
			}

			TerminalCommand tc = new TerminalCommand();
			tc.setVehicleId(vd.getEntityId());
			tc.setCmdType(0x9201);
			tc.setCmdData(sb.toString());
			SendCommand(tc);

			VideoRequest v = new VideoRequest();
			v.setSimNo(vd.getSimNo());
			v.setChannelId(channel);
			v.setStreamType(streamType);
			v.setPlateNo(tc.getPlateNo());
			v.setUserIp(this.getRequest().getRemoteAddr());
			v.setUserId(this.getOnlineUser().getEntityId());
			v.setUserName(this.getOnlineUser().getName());
			v.setSessionId(this.getSession().getId());
			v.setMediaType(VideoDataType.PLAY_BACK);
			onlineVideoRequestService.updateVideoRequest(v);

			return json(true, tc.getEntityId());
		} catch (Exception ex) {
			log.error(ex.getMessage(),ex);
			return json(false, ex.getMessage());
		}
	}


	@ResponseBody
	@RequestMapping("/controlPlayBack.action")
	public JsonMessage controlPlayBack(String plateNo, String simNo, int channelId, int playbackType, int speed,
									   Date playBackPos) {
		try {
			if(playBackPos == null)
				playBackPos = new Date();

			String sessionId = this.getSession().getId();
			StringBuilder sb = new StringBuilder();
			sb.append(channelId).append(";").append(playbackType).append(";").append(speed).append(";")
					.append(DateUtil.toStringByFormat(playBackPos, "yyyy-MM-dd HH:mm:ss"));
			VehicleData vd = null;
			if(StringUtil.isNullOrEmpty(plateNo) == false)
			   vd = this.vehicleDataService.getVehicleByPlateNo(plateNo);
			else if(StringUtil.isNullOrEmpty(simNo) == false)
			{
				if(simNo.length() > 11)
					simNo = simNo.substring(simNo.length() - 11);
				vd = this.vehicleDataService.getVehicleBySimNo(simNo);
			}
			if(vd == null)
			{
				return json(false, "平台没有此车辆:" + plateNo + "," + simNo);
			}
			TerminalCommand tc = new TerminalCommand();
			tc.setVehicleId(vd.getEntityId());
			tc.setCmdType(0x9202);
			tc.setCmdData(sb.toString());
			SendCommand(tc);

			//如果是结束回放
			if(playbackType == 2)
			{
				int streamType = this.getUserPreference().getStreamType();
				onlineVideoRequestService.stopVideoRequest(this.getOnlineUser().getEntityId(),vd.getSimNo(), channelId, sessionId, streamType, VideoDataType.PLAY_BACK);
			}

			return json(true, tc.getEntityId());
		} catch (Exception ex) {
			log.error(ex.getMessage(),ex);
			return json(false, ex.getMessage());
		}
	}


	/**
	 * 打开视频资源播放器页面，用于播放本地服务器的视频资源文件
	 * @param m
	 * @param strResourceIds
	 * @return
	 */
	@RequestMapping("/viewVideoResourcePlayer.action")
	public String viewVideoResourcePlayer(Model m, String strResourceIds)
	{
		String[] strResourceIdArray = strResourceIds.split(",");
		StringBuilder sb = new StringBuilder();
		StringBuilder sbKeyFrame = new StringBuilder();
		for(String strResourceId : strResourceIdArray)
		{
			if(sb.length() > 0)
				sb.append(",");
			long id = Long.parseLong(strResourceId);
			VideoFileItem vi = this.videoFileItemService.load(id);
			String mp4FilePath = null;
			if(VideoFileItem.FROM_FTP.equals(vi.getFileSource()))
			{
				String strDir = this.getVideoServerConfig().getFtpPath() + "\\" + vi.getFilePath();
				File file = searchFile(strDir);
				if(file != null) {
					if (file.getName().endsWith(".avi")) {
						this.processAVI(file.getPath());
					}
					mp4FilePath = file.getName().replace("avi", "mp4");
					mp4FilePath = vi.getFilePath() + "/" + mp4FilePath;
					sb.append(mp4FilePath);
				}
			}else
			{
				mp4FilePath = vi.getFilePath();
				sb.append((vi.getFilePath()));
			}

			String keyFrameStr = "";
			if(mp4FilePath != null)
			{
				VideoMp4KeyFrame v = this.videoMp4KeyFrameService.getVideoMp4KeyFrameByFileName(mp4FilePath);
				if(v != null)
				{
					keyFrameStr = v.getKeyFrames();
				}else
				{
					log.error("没有找到关键帧，Mp4文件:" + mp4FilePath);
				}
			}
			sbKeyFrame.append(keyFrameStr).append(";");
		}

		String resourceUrl =  sb.toString();
		m.addAttribute("videResourceUrls", sb.toString());
		m.addAttribute("strKeyFrame", sbKeyFrame.toString());
		//m.addAttribute("vehicleId", vehicleId);
		return "/video/videoPlayLocalResource";
	}

	// 对ffmpeg无法解析的文件格式(wmv9，rm，rmvb等), 可以先用别的工具（mencoder）转换为avi(ffmpeg能解析的)格式.
	private  String processAVI(String aviFileName) {
		if(aviFileName.indexOf(".avi") <= 0)
			return aviFileName;
		String mp4FileName = aviFileName.replace("avi","mp4");

		String ffmpegPaht = this.getVideoServerConfig().getFfmpegPath();
		List<String> commend = new ArrayList<String>();
		//commend.add("c:\\ffmpeg\\mencoder");
		commend.add(ffmpegPaht);
		commend.add("-i");
		commend.add(aviFileName);
		commend.add(mp4FileName);
		try {
			ProcessBuilder builder = new ProcessBuilder();
			builder.command(commend);
			builder.start();
			return "c:\\ffmpeg\\output\\a.avi";
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}



	public static File searchFile(String path) {// 递归查找包含关键字的文件
		File d = new File(path);
		File aviFile = null;
		if (d.isDirectory()) {
			File[] fs = d.listFiles();
			for (int i = 0; i < fs.length; i++) {
				File f = fs[i];
				String fileName = f.getName();
				if (fileName.endsWith(".mp4")) {
					return f;
				}else if(fileName.endsWith(".avi"))
				{
					aviFile = f;
				}
			}
			return aviFile;
		}else
		{
			return d;
		}

	}



}
